package com.lhy.admin.common.mvcplus.wrapper.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lhy.admin.common.mvcplus.entity.ComparatorEnum;
import com.lhy.admin.util.ReflectionUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * JSONObjectArrayContainsComparator
 *
 * @author hyluan
 * @date 2022年11月21日 14:11
 */
public class JSONObjectArrayContainsComparator extends AbstractJSONObjectComparator {

    public static final String JSON_CONTAINS_SQL_TEMP = "JSON_CONTAINS(%s,JSON_OBJECT('%s', {0}))";

    @Override
    @Nullable
    public Class getAttrFieldClass(QueryWrapper queryWrapper, String[] name) {
        Field field = ReflectionUtils.getFieldByDbFieldName(queryWrapper.getEntityClass(), name[0]);
        if (name.length > 1) {
            Type type = field.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType genericType = (ParameterizedType) type;
                Assert.isTrue(((Class) genericType.getRawType()).isAssignableFrom(List.class), "JSON_CONTAINS 字段：%s必须为List".formatted(name[0]));
                Class<Object> objectClass = ReflectionUtils.getParameterizedType(genericType, 0);
                Field attrField = ReflectionUtils.getDeclaredField(objectClass, name[1]);
                return attrField.getType();
            } else {
                Type genericSuperclass = ((Class) type).getGenericSuperclass();
                if (genericSuperclass instanceof ParameterizedType genericType) {
                    Class<Object> objectClass = ReflectionUtils.getParameterizedType(genericType, 0);
                    Field attrField = ReflectionUtils.getDeclaredField(objectClass, name[1]);
                    return attrField.getType();
                } else {
                    throw new RuntimeException("JSON_CONTAINS 字段：%s不含泛型参数".formatted(name[0]));
                }
            }
        }
        return field.getClass();
    }

    public static String sql(String colName, String attrName) {
        return JSON_CONTAINS_SQL_TEMP.formatted(colName, attrName);
    }

    @Override
    public String expressionSql(String colName, String attrName) {
        return sql(colName, attrName);
    }


    @Override
    public ComparatorEnum comparatorEnum() {
        return ComparatorEnum.JSON_OBJECT_CONTAINS;
    }
}
